//
//  CZEmoticonManange.swift
//  swiftweibo
//
//  Created by ffxk007 on 2017/7/6.
//  Copyright © 2017年 ffxk007. All rights reserved.
//file:///Users/ffxk007/Desktop/weiboswfit/swiftweibo/swiftweibo/Class/Tools/CZEmoticonManager.swift: warning: Missing file: /Users/ffxk007/Desktop/weiboswfit/swiftweibo/swiftweibo/Class/Tools/CZEmoticonManager.swift is missing from working copy


import Foundation
import UIKit

class CZEmoticonManager {
    
    /// 为了表情复用，建立一个单例，值加载一次表情数据
    
    /// 表情管理器的单例
    static let shared = CZEmoticonManager()
    
    /// 表情包的懒加载数组
    lazy var packages = [CZEmoticonPackage]()
    
    /// 表情素材的bundle
    lazy var boundle:Bundle = {
        let path = Bundle.main.path(forResource: "HMEmoticon.bundle", ofType: nil)
        return Bundle(path: path!)!
    }()
    
    /// 构造函数,如果在init之前增加fileprivate修饰符，可以要求调用者必须通过shared访问对象
    //OC 要重写allocwithzone
    fileprivate init() {
        loadPackages()
    }
}
//MARK:-表情符号处理
extension CZEmoticonManager {
    
    
    /// 将给定的字符串转换成属性文本
    ///
    /// - Parameters:
    ///   - string: 完整的字符串
    ///   - font: 字体额大小
    /// - Returns: 属性文本
    func emotionString(string:String,font:UIFont) -> NSAttributedString {
        let attrString = NSMutableAttributedString(string: string)
        
        //1.建立正则表达式，过滤所有的表情文字
        // [] ()都是正则表达式烦人关键字，如果要参与匹配，需要转义
        let pattern = "\\[.*?\\]"
        
        guard let regx = try? NSRegularExpression(pattern: pattern, options: []) else {
            return attrString
        }
        
        //2.匹配所有项
        let matches = regx.matches(in: string, options: [], range: NSRange(location: 0, length: attrString.length))
        
        //3.遍历所有匹配结果
        for m in matches.reversed() {
            let r = m.rangeAt(0)
            let subStr = (attrString.string as NSString).substring(with: r)
            
            //1.使用subStr查找对应的表情符号
            if let em = CZEmoticonManager.shared.findEmoticon(string: subStr) {
                
                //2.使用表情符号中的属性文本，替换原有的属性文本内容
                attrString.replaceCharacters(in: r, with: em.imageText(font: font))
            }
        }
        
        //4.***统一设置一遍字符串的属性,除了设置字体还需要设置颜色
        attrString.addAttributes([NSFontAttributeName:font,NSForegroundColorAttributeName:UIColor.darkGray], range: NSRange(location: 0, length: attrString.length))
        
        return attrString
    }
    /// 根据string在所有的表情符号中查找对应的表情模型对象
    ///
    /// 如果找到返回表情模型
    /// 否则返回nil
    func findEmoticon(string:String) -> CZEmoticon? {
        //1.遍历表情包
        //OC中过滤数组使用[谓词]
        for p in packages {
            //2.在表情数组中过滤string
            
            //方法一
//           let result = p.emoticons.filter({ (em) -> Bool in
//                return em.chs == string
//            })
            
            //方法二-尾随闭包
//            let result = p.emoticons.filter() { (em) -> Bool in
//                return em.chs == string
//            }
            //方法三-如果闭包中只有一句，并且是返回
            //闭包格式定义可以省略
            //参数省略之后使用$0 $1一次替代原有的参数
//            let result = p.emoticons.filter() {
//                return $0.chs == string
//            }
            
            //方法四-如果闭包中只有一句，并且是返回
            //闭包格式定义可以省略
            //参数省略之后使用$0 $1一次替代原有的参数
            //return也可以省略
            let result = p.emoticons.filter() { $0.chs == string }

            
            //3.判断结果
            if result.count == 1 {
                return result[0]
            }
        }
        
        return nil
    }
}
//MARK:-表情包数据处理

fileprivate  extension CZEmoticonManager {
    func loadPackages() {
        
        //读取bundle的plist
        //只要按照bundle默认的目录结构设定，就可以直接读取resources目录下的文件
        guard let path = Bundle.main.path(forResource: "HMEmoticon.bundle", ofType: nil),
            let bundle = Bundle(path: path),
            let plistPath = bundle.path(forResource: "emoticons.plist", ofType: nil),
            let array = NSArray(contentsOfFile: plistPath) as? [[String:String]],
            let models = NSArray.yy_modelArray(with: CZEmoticonPackage.self, json: array) as?[CZEmoticonPackage]
            else {
                
                return
        }
        //设置表情包数据
        //使用+=不需要给packages分配空间，直接追加数据
        packages += models

    }
}

